package org.andromeo.connectionapi;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.andromeo.ARException;
import org.andromeo.ARUtil;
import org.andromeo.GRSession;
import org.andromeo.util.ARRequester;

public class LoginProcessor {

	// Konstanten
	public static final int PROCESS_LOGIN = 1;
	public static final int LOGIN_SUCCESSFUL = 2;
	public static final int NOT_LOGGED_IN = 3;
	public static final int SESSION_TIME_OUT = 4;
	public static final int NAME_PASSWORD_INCORRECT = 5;
	public static final int PASSWORD_LENGTH_OK = 6;
	public static final int PASSWORD_LENGTH_TOO_SMALL = 7;
	public static final int VALIDATION_OK = 8;

	// REGEX Parser Patterns
	// first aframePattern should be iterally matched. the containing
	// group(0)-string
	// then has to be matched against autherrPattern.
	// if last match was successful, we have a login problem.
	public static Pattern aframePattern = Pattern.compile("<(a)|(frame).*?>",
			Pattern.DOTALL);
	public static Pattern autherrPattern = Pattern.compile("authError",
			Pattern.DOTALL);

	private static int pwdCheck(String pwd) {
		if (pwd != null && pwd.length() >= 6)
			return VALIDATION_OK;
		else
			return PASSWORD_LENGTH_TOO_SMALL;
	}

	private static String createPwdPostMsg(GRSession grsession, String password)
			throws UnsupportedEncodingException {

		String data = URLEncoder.encode("PHPSESSID", "UTF-8") + "="
				+ URLEncoder.encode(grsession.getPhpSessionID(), "UTF-8");

		data += "&" + URLEncoder.encode("username", "UTF-8") + "="
				+ URLEncoder.encode(grsession.getUsername(), "UTF-8");

		data += "&" + URLEncoder.encode("passwort", "UTF-8") + "="
				+ URLEncoder.encode(ARUtil.encodeROT13(password), "UTF-8");

		data += "&" + URLEncoder.encode("status", "UTF-8") + "="
		+ String.valueOf(grsession.getStatus());

		data += "&" + URLEncoder.encode("secure", "UTF-8") + "=";
		data += "&" + URLEncoder.encode("resX", "UTF-8") + "="
				+ URLEncoder.encode("500", "UTF-8");
		data += "&" + URLEncoder.encode("resY", "UTF-8") + "="
				+ URLEncoder.encode("500", "UTF-8");
		return data;
	}

	public static synchronized int login(GRSession grsession, String pwd)
			throws ARException, IOException {
		String urlstring = grsession.getGrurl();
		int statusLogin = pwdCheck(pwd);
		String postmsg = createPwdPostMsg(grsession, pwd);

		if (statusLogin == PASSWORD_LENGTH_TOO_SMALL) {
			grsession.setSessionStatus(GRSession.STATUS_ERR_WRONG_PASSWORD);
			throw new ARException(ARException.AREXC_WRONG_USER_PASSWORD);
		}

		String response = ARRequester
				.sendRequest(grsession, urlstring, postmsg);

		// check response for any login problems
		statusLogin = LOGIN_SUCCESSFUL;
		Matcher aframeMatcher = aframePattern.matcher(response);
		Matcher autherrMatcher = null;
		while (aframeMatcher.find()) {
			String tagstring = aframeMatcher.group();
			autherrMatcher = autherrPattern.matcher(tagstring);
			if (autherrMatcher.find())
				statusLogin = NAME_PASSWORD_INCORRECT;
		}

		// throw exception if login was unsuccessful
		if (statusLogin != LOGIN_SUCCESSFUL)
			throw new ARException(ARException.AREXC_WRONG_USER_PASSWORD);
		return statusLogin;
	}
}
